/**
 * 阅读指南：
 * 导出数据测试：搜索 「exportDataByUser」关键字，找到函数即可
 * 导出接口数据：搜索「exportApiDemo」关键字，找到函数即可
 * 导出复杂表头：搜索「exportExtendDemo」关键字，找到函数即可
 * 批量设置样式：搜索「exportStyleDemo」关键字，找到函数即可
 * 简单文件导入：搜索「uploadExcel」可找到导入的处理逻辑，拖拽文件/选择文件回调获取files对象请搜索「#LAY-excel-import-excel」
 * upload模块：搜索「uploadInst」查看使用逻辑，导入相关逻辑同上
 */

layui.use(['jquery', 'layer', 'upload', 'excel', 'laytpl', 'element', 'code'], function(){
  var $ = layui.jquery;
  var layer = layui.layer;
  var upload = layui.upload;
  var excel = layui.excel;
  var laytpl = layui.laytpl;
  var element = layui.element;


 /**
  * 上传excel的处理函数，传入文件对象数组
  * @param  {[type]} files [description]
  * @return {[type]}       [description]
  */
 function uploadExcel(files) {
   try {
     excel.importExcel(files, {
       // 读取数据的同时梳理数据
       fields: {
         'id': 'A'
         ,'username': 'B'
         ,'experience': 'C'
         ,'sex': 'D'
         ,'score': 'E'
         ,'city': 'F'
         ,'classify': 'G'
         ,'wealth': 'H'
         ,'sign': 'I'
       }
     }, function(data) {
       // 还可以再进行数据梳理
/*						data = excel.filterImportData(data, {
         'id': 'A'
         ,'username': 'B'
         ,'experience': 'C'
         ,'sex': 'D'
         ,'score': 'E'
         ,'city': 'F'
         ,'classify': 'G'
         ,'wealth': 'H'
         ,'sign': 'I'
       });
*/
      // 如果不需要展示直接上传，可以再次 $.ajax() 将JSON数据通过 JSON.stringify() 处理后传递到后端即可
      layer.open({
         title: '文件转换结果'
         ,area: ['799px', '399px']
         ,tipsMore: true
         ,content: laytpl($('#LAY-excel-export-ans').html()).render({data: data, files: files})
         ,success: function() {
           element.render('tab');
           layui.code({
           });
         }
       });
     });
   } catch (e) {
     layer.alert(e.message);
   }
 };
 //upload上传实例
 var uploadInst = upload.render({
   elem: '#LAY-excel-upload' //绑定元素
   ,url: '/upload/' //上传接口（PS:这里不用传递整个 excel）
   ,auto: false //选择文件后不自动上传
   ,accept: 'file'
   ,choose: function(obj) {// 选择文件回调
     var files = obj.pushFile();
     files = Object.values(files);// 注意这里的数据需要是数组，所以需要转换一下
     uploadExcel(files);
   }
 });

  $(function(){
    // 监听上传文件的事件
    $('#LAY-excel-import-excel').change(function(e) {
      var files = e.target.files;
      uploadExcel(files);
    });
    // 文件拖拽
    $('body')[0].ondragover = function(e) {
      e.preventDefault();
    }
    $('body')[0].ondrop = function(e) {
      e.preventDefault();
      var files = e.dataTransfer.files;
      uploadExcel(files);
    }
  });
});
/**
 * 上传excel的处理函数，传入文件对象数组
 * @param  {[type]} files [description]
 * @return {[type]}       [description]
 */
function uploadExcel(files) {
  layui.use(['excel', 'layer'], function() {
    var excel = layui.excel;
    var layer = layui.layer;
    try {
      excel.importExcel(files, {
        // 读取数据的同时梳理数据
        fields: {
          'id': 'A'
          ,'username': 'B'
          ,'experience': 'C'
          ,'sex': 'D'
          ,'score': 'E'
          ,'city': 'F'
          ,'classify': 'G'
          ,'wealth': 'H'
          ,'sign': 'I'
        }
      }, function(data) {
        // 还可以再进行数据梳理
  /*						data = excel.filterImportData(data, {
          'id': 'A'
          ,'username': 'B'
          ,'experience': 'C'
          ,'sex': 'D'
          ,'score': 'E'
          ,'city': 'F'
          ,'classify': 'G'
          ,'wealth': 'H'
          ,'sign': 'I'
        });
  */
       // 如果不需要展示直接上传，可以再次 $.ajax() 将JSON数据通过 JSON.stringify() 处理后传递到后端即可
       layer.open({
          title: '文件转换结果'
          ,area: ['800px', '400px']
          ,tipsMore: true
          ,content: laytpl($('#LAY-excel-export-ans').html()).render({data: data, files: files})
          ,success: function() {
            element.render('tab');
            layui.code({
            });
          }
        });
      });
    } catch (e) {
      layer.alert(e.message);
    }
  });
};
/**
 * 导出数据的测试
 * @return {[type]} [description]
 */
function exportDataByUser() {
  layui.use(['layer'], function() {
    layer.ready(function(){
      layer.prompt({
        title: '请输入测试数据量(9列)'
        ,value: 3000
      }, function(value, index, elem) {
        // 使用setTimeout、async、ajax等方式可以实现异步导出
        setTimeout(function(){
          var num = parseInt(value);
          var timestart = Date.now();
          exportDataTest(num);
          var timeend = Date.now();

          var spent = (timeend - timestart) / 1000;
          layer.alert('耗时 '+spent+' s');
        }, 0)
        layer.close(index);
      });
    });
  });
}
/**
 * 导出接口数据的样例
 * @return {[type]} [description]
 */
function exportApiDemo(url) {
  layui.use(['jquery', 'excel', 'layer'], function() {
    var $ = layui.jquery;
    var layer = layui.layer;
    var excel = layui.excel;

    // 模拟从后端接口读取需要导出的数据
    $.ajax({
      url: url
      ,dataType: 'json'
      ,success: function(res) {
        var data = res.data;
        // 重点！！！如果后端给的数据顺序和映射关系不对，请执行梳理函数后导出
        data = excel.filterExportData(data, {
          id: 'id'
          ,username: 'username'
          ,experience: 'experience'
          ,sex: 'sex'
          ,score: function(value, line, data) {
            // 可以直接指定类型为数字
            return {
              v: value,
              t: 'n'
            }
          }
          ,city: function(value, line, data) {
            return {
              v: value,
              s: { font: { sz: 14, bold: true, color: { rgb: "FFFFAA00" } }, fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FFFF00" } } }
            };
          }
          ,classify: 'classify'
          ,wealth: 'wealth'
          ,sign: 'sign'
        });
        // 重点2！！！一般都需要加一个表头，表头的键名顺序需要与最终导出的数据一致
        data.unshift({ id: "ID", username: "用户名", experience: '积分', sex: '性别', score: '评分', city: '城市', classify: '职业', wealth: '财富', sign: '签名' });

        var timestart = Date.now();
        excel.exportExcel({
          sheet1: data
        }, '导出接口数据.xlsx', 'xlsx');
        var timeend = Date.now();

        var spent = (timeend - timestart) / 1000;
        layer.alert('单纯导出耗时 '+spent+' s');
      }
      ,error: function() {
        layer.alert('获取数据失败，请检查是否部署在本地服务器环境下');
      }
    });
  });
}
/**
 * 导出 total 数据测试
 * @param  {[type]} total [description]
 * @return {[type]}       [description]
 */
function exportDataTest(total) {
  layui.use(['excel'], function() {
    var excel = layui.excel;

    // 如果数据量特别大，最好直接传入 AOA 数组，减少内存/CPU消耗
    var data = [
      [ "ID", "用户名", '积分', '性别', '评分', '城市', '签名', '职业', '财富' ]
    ];
    if (total > 0 ) {
      // 造 num 条数据
      for (var i = 0; i < total; i++) {
        data.push([
          'LAY-'+i,
          'test'+i,
          '男',
          200,
          100,
          '魔都',
          'test'+i,
          '程序猿',
          100 * i,
        ]);
      }
    }

    excel.exportExcel({
      sheet1: data
    }, '测试导出'+total+'条数据.xlsx', 'xlsx');
  });
}
/**
 * 导出复杂表头数据问题
 * @return {[type]} [description]
 */
function exportExtendDemo() {
  layui.use(['excel'], function() {
    var excel = layui.excel;
    var data = [
      { id: '标志位', username: {
        v: '用户信息', s: {
          alignment: {
            horizontal: 'center',
            vertical: 'center'
          },
          fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FF0000" }}
        }
      }, age: '', sex: '', score: '', classify: '' },// 被合并的列数据也需要填充上
      { id: 'ID', username: '基础信息', age: '', sex: '', score: '扩展数据', classify: '' },
      { id: 'id', username: '用户名', age: '年龄', sex: '性别', score: '积分', classify: '职业' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
      { id: 1, username: 'wang', age: 10, sex: '男', score: 100, classify: '程序猿' },
    ];
    // 生成配置的辅助函数，返回结果作为扩展功能的配置参数传入即可
    // 1. 复杂表头合并[B1,C1,D1][E1,F1]
    var mergeConf = excel.makeMergeConfig([
      ['B1', 'F1'],
      ['B2', 'D2'],
      ['E2', 'F2'],
    ]);
    // 2. B列宽 150，F列宽200，默认80
    var colConf = excel.makeColConfig({
      'B': 150,
      'F': 200,
    }, 80);
    // 3. 第1行行高40，第二行行高30，默认20
    var rowConf = excel.makeRowConfig({
      1: 40,
      3: 30
    }, 20);
    // 4. 公式的用法
    data.push({
      id: '',
      username: '总年龄',
      age: {t: 'n', f: 'SUM(C4:C10)'},
      sex: '总分',
      score: {t: 'n', f: 'SUM(E4:E10)'},
      classify: {
        v: '注意：保护模式中公式无效，请「启用编辑」',
        s: { font: {color: {rgb: 'FF0000'}} }
      }
    });
    excel.exportExcel({
      sheet1: data,
      sheet2: data
    }, '测试导出复杂表头.xlsx', 'xlsx', {
      extend: {
        // extend 中可以指定某个 sheet 的属性，如果不指定 sheet 则所有 sheet 套用同一套属性
        sheet1: {
          '!merges': mergeConf
          ,'!cols': colConf
          ,'!rows': rowConf
        }
      }
    });
  });
}

/**
 * 快速设置样式使用方法
 */
function exportStyleDemo() {
  layui.use(['excel'], function () {
    var excel = layui.excel;
    var data = [
      { username: '520',sex: '男', city: 'J', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '女', city: 'X', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' },
      { username: '520',sex: '男', city: '上海', 'score': 100, 'start': '2019-03-11' }
    ];// 假设的后台的数据
    // 1. 使用filter梳理一下
    data = excel.filterExportData(data, {
      name: 'username',
      sex:'sex',
      score:'score',
      start:'start',
      // 这里设置的样式会被合并
      city: function(value) {
        return {
          v: value,
          s: {
            font: { sz: 14, bold: true, color: { rgb: "FFFFAA00" } },
            alignment: {
              horizontal: 'center',
              vertical: 'center'
            }
          }
        }
      },
      start2:'start',
      score2:'score',
      sex2:'sex',
      name2: 'username'
    });
    // 笔芯彩蛋（JeffreyWang 2019-03-11）
    var heart = [
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 1, 1, 0, 1, 1, 0, 0],
      [0, 1, 1, 1, 1, 1, 1, 1, 0],
      [1, 1, 1, 1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1, 1, 1, 1],
      [0, 1, 1, 1, 1, 1, 1, 1, 0],
      [0, 0, 1, 1, 1, 1, 1, 0, 0],
      [0, 0, 0, 1, 1, 1, 1, 0, 0],
      [0, 0, 0, 0, 1, 0, 0, 0, 0],
    ];
    // 2. 调用设置样式的函数，传入设置的范围，支持回调
    excel.setExportCellStyle(data, 'A1:I9', {
      s: {
        fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FF0000" } },
        alignment: {
          horizontal: 'center',
          vertical: 'center'
        }
      }
    }, function(cell, newCell, row, config, currentRow, currentCol, fieldKey) {
      // 回调参数，cell:原有数据，newCell:根据批量设置规则自动生成的样式，row:所在行数据，config:传入的配置,currentRow:当前行索引,currentCol:当前列索引，fieldKey:当前字段索引
      // return ((currentRow + currentCol) % 2 === 0) ? newCell : cell;// 隔行隔列上色
      return (heart[currentRow] && heart[currentRow][currentCol]) ? newCell : cell; // 根据阵列，给心形上色
      // return newCell;
    } );
    // console.log(data);
    // 3. 单元格样式优化为正方形
    var colConfig = excel.makeColConfig({
      'A': 80,
      'I': 80
    }, 80);
    var rowConfig = excel.makeRowConfig({
      1: 40,
      9: 40
    }, 40);
    excel.exportExcel(data, '批量设置样式.xlsx', 'xlsx', {
      extend: {
        '!cols': colConfig,
        '!rows': rowConfig
      }
    });
  });
}




